package com.baijiayun.live.ui.chat;

import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.StateListDrawable;
import android.os.Build;
import android.os.Bundle;
import android.text.Editable;
import android.text.InputFilter;
import android.text.Spanned;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.core.content.ContextCompat;
import androidx.core.view.GravityCompat;
import androidx.fragment.app.FragmentTransaction;

import com.baijiahulian.common.cropperv2.BJCommonImageCropHelper;
import com.baijiahulian.common.cropperv2.ThemeConfig;
import com.baijiahulian.common.cropperv2.model.PhotoInfo;
import com.baijiayun.live.ui.R;
import com.baijiayun.live.ui.base.BaseDialogFragment;
import com.baijiayun.live.ui.chat.emoji.EmojiFragment;
import com.baijiayun.live.ui.chat.emoji.EmojiPresenter;
import com.baijiayun.live.ui.chat.privatechat.ChatUsersDialogFragment;
import com.baijiayun.live.ui.utils.QueryPlus;
import com.baijiayun.livecore.models.LPExpressionModel;
import com.baijiayun.livecore.utils.CommonUtils;
import com.baijiayun.liveuibase.utils.ThemeDataUtil;
import com.baijiayun.liveuibase.utils.drawable.DrawableBuilder;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import static android.content.Context.INPUT_METHOD_SERVICE;

/**
 * Created by Shubo on 2017/3/4.
 */

public class MessageSendFragment extends BaseDialogFragment implements MessageSendContract.View {
    private static final String QUICK_REPLY_FILE_NAME = "live_ui_quick_reply";
    private MessageSendContract.Presenter presenter;
    private QueryPlus $;
    private MessageTextWatcher textWatcher;
    private EmojiFragment emojiFragment;
    private ChatUsersDialogFragment chatUsersDialogFragment;
    private boolean autoChoosePrivateChatUser = false;
    private String autoEnterMessage = "";
    private static final int MAX_TEXT_LENGTH = 400;
    private Map<String, Integer> mChatQuickReplyMap;

    public static MessageSendFragment newInstance() {
        return new MessageSendFragment();
    }

    @Override
    public int getLayoutId() {
        return R.layout.bjy_dialog_message_send;
    }

    @Override
    protected void setWindowParams(WindowManager.LayoutParams windowParams) {
        windowParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
        windowParams.width = WindowManager.LayoutParams.MATCH_PARENT;
        windowParams.gravity = Gravity.BOTTOM | GravityCompat.END;
        windowParams.windowAnimations = R.style.BJYLiveBaseSendMsgDialogAnim;
    }

    @Override
    protected void init(Bundle savedInstanceState, Bundle arguments) {
        super.hideTitleBar();
        $ = QueryPlus.with(contentView);
        textWatcher = new MessageTextWatcher();

        ((EditText) $.id(R.id.dialog_message_send_et).view()).addTextChangedListener(textWatcher);

        ((EditText) $.id(R.id.dialog_message_send_et).view()).setFilters(new InputFilter[]{
                new LengthFilter(MAX_TEXT_LENGTH)
        });

        ((EditText) $.id(R.id.dialog_message_send_et).view()).setOnEditorActionListener((v, actionId, event) -> {
            if (actionId == EditorInfo.IME_ACTION_SEND && $.id(R.id.dialog_message_send_btn).view().isEnabled()) {
                sendMessage();
            }
            return true;
        });
        if (presenter.isLiveCanWhisper()) {
            showPrivateChatChange();
        } else {
            $.id(R.id.dialog_private_chat_btn).gone();
            $.id(R.id.dialog_interval_line).gone();
        }

        $.id(R.id.dialog_message_send_et).view().postDelayed(() -> {
            if (getActivity() == null) return;
            InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(INPUT_METHOD_SERVICE);
            if (imm == null) return;
            imm.showSoftInput($.id(R.id.dialog_message_send_et).view(), InputMethodManager.SHOW_IMPLICIT);
        }, 100);

        $.id(R.id.dialog_message_send_et).clicked(v -> {
            if (chatUsersDialogFragment != null) {
                $.id(R.id.dialog_private_chat_users).gone();
                FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
                transaction.remove(chatUsersDialogFragment);
                if (Build.VERSION.SDK_INT >= 24) {
                    transaction.commitNowAllowingStateLoss();
                } else {
                    transaction.commitAllowingStateLoss();
                }
                chatUsersDialogFragment = null;
            } else if (emojiFragment != null) {
                $.id(R.id.dialog_message_send_emoji).gone();
                FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
                transaction.remove(emojiFragment);
                if (Build.VERSION.SDK_INT >= 24) {
                    transaction.commitNowAllowingStateLoss();
                } else {
                    transaction.commitAllowingStateLoss();
                }
                emojiFragment = null;
            }

            InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(INPUT_METHOD_SERVICE);
            if (!imm.isActive()) {
                imm.showSoftInput($.id(R.id.dialog_message_send_et).view(), InputMethodManager.SHOW_IMPLICIT);
            }
        });

        $.id(R.id.dialog_message_send_btn).clicked(v -> sendMessage());

        $.id(R.id.dialog_message_send_pic).clicked(v -> {
            ThemeConfig.Builder builder = new ThemeConfig.Builder();
            builder.setMainElementsColor(
                    ThemeDataUtil.getColorFromThemeConfigByAttrId(getContext(), R.attr.base_theme_live_product_color));
            BJCommonImageCropHelper.openImageSingleAblum(getActivity(), BJCommonImageCropHelper.PhotoCropType.None, builder.build(), new BJCommonImageCropHelper.OnHandlerResultCallback() {
                @Override
                public void onHandlerSuccess(List<PhotoInfo> list) {
                    if (list.size() == 1) {
                        presenter.sendPicture(list.get(0).getPhotoPath());
                    }
                }

                @Override
                public void onHandlerFailure(String s) {
                    showToast(s);
                }
            });
        });
        if (presenter.canSendPicture()) {
            $.id(R.id.dialog_message_send_pic).visible();
        } else {
            $.id(R.id.dialog_message_send_pic).gone();
        }

        $.id(R.id.dialog_message_emoji).clicked(v -> presenter.chooseEmoji());

        $.id(R.id.dialog_message_send_container).backgroundDrawable(getInputBG());

        $.id(R.id.dialog_private_chat_btn).clicked(v -> presenter.choosePrivateChatUser());

        $.id(R.id.dialog_message_send_btn).enable(false);
        if (autoChoosePrivateChatUser) {
            presenter.choosePrivateChatUser();
            autoChoosePrivateChatUser = false;
        } else {
            $.id(R.id.dialog_message_send_et).view().requestFocus();
        }
        if (!TextUtils.isEmpty(autoEnterMessage)) {
            EditText editText = ((EditText) $.id(R.id.dialog_message_send_et).view());
            editText.post(() -> {
                editText.setText(autoEnterMessage);
                editText.setSelection(autoEnterMessage.length());
            });
        }
        SharedPreferences sharedPreferences = getContext().getSharedPreferences(QUICK_REPLY_FILE_NAME, Context.MODE_PRIVATE);
        mChatQuickReplyMap = (Map<String, Integer>) sharedPreferences.getAll();
        presenter.getChatQuickReplyList();
    }

    private Drawable getInputBG() {
        StateListDrawable rstDrawable = new StateListDrawable();
        if (getContext() == null) {
            return rstDrawable;
        }
        rstDrawable.addState(new int[]{android.R.attr.state_enabled}
                , new DrawableBuilder()
                        .solidColor(ThemeDataUtil.getColorFromThemeConfigByAttrId(getContext(), R.attr.base_theme_window_bg_color))
                        .cornerRadius(getContext().getResources().getDimensionPixelSize(R.dimen.bjy_base_common_bg_radius))
                        .strokeColor(ContextCompat.getColor(getContext(), R.color.base_bg_stroke))
                        .strokeWidth(1)
                        .build());
        rstDrawable.addState(new int[]{-android.R.attr.state_enabled}
                , new DrawableBuilder()
                        .solidColor(ThemeDataUtil.getColorFromThemeConfigByAttrId(getContext(), R.attr.base_theme_window_bg_color))
                        .cornerRadius(getContext().getResources().getDimensionPixelSize(R.dimen.bjy_base_common_bg_radius))
                        .strokeColor(ContextCompat.getColor(getContext(), R.color.base_bg_stroke))
                        .strokeWidth(1)
                        .build());
        return rstDrawable;
    }

    @Override
    public void onResume() {
        super.onResume();
        updateChatQuickReplyArea();
    }

    public void setAutoChoosePrivateChatUser(boolean autoChoosePrivateChatUser) {
        this.autoChoosePrivateChatUser = autoChoosePrivateChatUser;
    }

    public void setEnterMessage(String autoEnterMessage) {
        this.autoEnterMessage = autoEnterMessage;
    }

    private void sendMessage() {
        if (presenter.isAllForbidden() && !presenter.canWisperTeacherInForbidAllMode()) {
            showToast(getString(R.string.live_forbid_send_message));
            dismissAllowingStateLoss();
            return;
        }
        final EditText editText = (EditText) $.id(R.id.dialog_message_send_et).view();
        LPExpressionModel singleEmoji = presenter.getSingleEmoji(editText.getText().toString().trim());
        if (singleEmoji != null) {
            final Object tag = editText.getTag();
            if (tag instanceof LPExpressionModel && tag != singleEmoji) {
                LPExpressionModel expressionModel = (LPExpressionModel) tag;
                // name或者key重复则以选中的为主
                if (TextUtils.equals(expressionModel.name,singleEmoji.name)) {
                    singleEmoji = expressionModel;
                } else if (TextUtils.equals(expressionModel.key, singleEmoji.key)) {
                    singleEmoji = expressionModel;
                }
            }
            if (presenter.isPrivateChat()) {
                presenter.sendEmojiToUser("[" + singleEmoji.getKey() + "]");
            } else {
                if (presenter.isAllForbidden()) {
                    showToast(getString(R.string.live_forbid_send_message));
                    dismissAllowingStateLoss();
                    return;
                }
                presenter.sendEmoji("[" + singleEmoji.getKey() + "]");
            }
        } else {
            if (presenter.isPrivateChat()) {
                presenter.sendMessageToUser(((EditText) $.id(R.id.dialog_message_send_et).view())
                        .getEditableText().toString());
            } else {
                if (presenter.isAllForbidden()) {
                    showToast(getString(R.string.live_forbid_send_message));
                    dismissAllowingStateLoss();
                    return;
                }
                presenter.sendMessage(((EditText) $.id(R.id.dialog_message_send_et).view())
                        .getEditableText().toString());
            }
            dismissAllowingStateLoss();
        }
        editText.setTag(null);
    }

    @Override
    public void onStart() {
        super.onStart();
    }


    @Override
    public void setPresenter(MessageSendContract.Presenter presenter) {
        super.setBasePresenter(presenter);
        this.presenter = presenter;
    }

    @Override
    public void showPrivateChatChange() {
        if (!presenter.isLiveCanWhisper()) return;
        if (presenter.isPrivateChat()) {
            ((EditText) $.id(R.id.dialog_message_send_et).view()).setHint(getString(R.string.private_chat) + CommonUtils.getEncodePhoneNumber(presenter.getPrivateChatUser().getName()));
            ($.id(R.id.dialog_private_chat_btn).view()).setSelected(true);
            ((TextView) $.id(R.id.dialog_private_chat_btn).view()).setTextColor(getResources().getColor(R.color.base_white));
        } else {
            ((EditText) $.id(R.id.dialog_message_send_et).view()).setHint(getString(R.string.live_input_chat));
            ($.id(R.id.dialog_private_chat_btn).view()).setSelected(false);
            ((TextView) $.id(R.id.dialog_private_chat_btn).view()).setTextColor(
                    ThemeDataUtil.getColorFromThemeConfigByAttrId(getContext(), R.attr.base_theme_window_assistant_text_color));
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        ((EditText) $.id(R.id.dialog_message_send_et).view()).removeTextChangedListener(textWatcher);
        $ = null;
        presenter = null;
        SharedPreferences sharedPreferences = getContext().getSharedPreferences(QUICK_REPLY_FILE_NAME, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.clear();
        for (Map.Entry<String, Integer> quickReply : mChatQuickReplyMap.entrySet()) {
            editor.putInt(quickReply.getKey(), quickReply.getValue());
        }
        editor.apply();
    }

    @Override
    public void showMessageSuccess() {
        $.id(R.id.dialog_message_send_et).text("");
        dismissAllowingStateLoss();
    }

    @Override
    public void showPrivateChatUserPanel() {
        if (!presenter.isLiveCanWhisper()) return;
        if (chatUsersDialogFragment == null && emojiFragment == null) {
            InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(INPUT_METHOD_SERVICE);
            if (imm.isActive()) {//isOpen若返回true，则表示输入法打开
                imm.hideSoftInputFromWindow($.id(R.id.dialog_message_send_et).view().getWindowToken(), 0);
            }

            contentView.postDelayed(() -> {
                if ($ == null) return;
                $.id(R.id.dialog_private_chat_users).visible();
                chatUsersDialogFragment = new ChatUsersDialogFragment();
                if (presenter.isPrivateChat()) {
                    chatUsersDialogFragment.initPrivateChatLabel(presenter.getPrivateChatUser());
                }
                FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
                transaction.add(R.id.dialog_private_chat_users, chatUsersDialogFragment);
                if (Build.VERSION.SDK_INT >= 24) {
                    transaction.commitNowAllowingStateLoss();
                } else {
                    transaction.commitAllowingStateLoss();
                }
            }, 100);


        } else if (emojiFragment != null) {
            InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(INPUT_METHOD_SERVICE);
            if (imm.isActive()) {//isOpen若返回true，则表示输入法打开
                imm.hideSoftInputFromWindow($.id(R.id.dialog_message_send_et).view().getWindowToken(), 0);
            }

            $.id(R.id.dialog_message_send_emoji).gone();
            FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
            transaction.remove(emojiFragment);
            if (Build.VERSION.SDK_INT >= 24) {
                transaction.commitNowAllowingStateLoss();
            } else {
                transaction.commitAllowingStateLoss();
            }
            emojiFragment = null;

            $.id(R.id.dialog_private_chat_users).visible();
            chatUsersDialogFragment = new ChatUsersDialogFragment();
            if (presenter.isPrivateChat()) {
                chatUsersDialogFragment.initPrivateChatLabel(presenter.getPrivateChatUser());
            }
            FragmentTransaction _transaction = getChildFragmentManager().beginTransaction();
            _transaction.add(R.id.dialog_private_chat_users, chatUsersDialogFragment);
            if (Build.VERSION.SDK_INT >= 24) {
                _transaction.commitNowAllowingStateLoss();
            } else {
                _transaction.commitAllowingStateLoss();
            }

        } else {

            $.id(R.id.dialog_private_chat_users).gone();
            FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
            transaction.remove(chatUsersDialogFragment);
            if (Build.VERSION.SDK_INT >= 24) {
                transaction.commitNowAllowingStateLoss();
            } else {
                transaction.commitAllowingStateLoss();
            }
            chatUsersDialogFragment = null;

            InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
            if (!imm.isActive())
                imm.showSoftInput($.id(R.id.dialog_message_send_et).view(), InputMethodManager.SHOW_IMPLICIT);
        }
    }

    @Override
    public void showEmojiPanel() {
        if (emojiFragment == null && chatUsersDialogFragment == null) {
            // hide keyborad
            InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
            if (imm.isActive()) {//isOpen若返回true，则表示输入法打开
                imm.hideSoftInputFromWindow($.id(R.id.dialog_message_send_et).view().getWindowToken(), 0);
            }

            contentView.postDelayed(() -> {
                if ($ == null) return;
                $.id(R.id.dialog_message_send_emoji).visible();
                emojiFragment = EmojiFragment.newInstance();
                EmojiPresenter emojiPresenter = new EmojiPresenter(emojiFragment);
                emojiPresenter.setRouter(presenter.getLiveRouterListener());
                emojiFragment.setPresenter(emojiPresenter);
                emojiFragment.setCallBack(emoji -> {
                    EditText etMsg = (EditText) $.id(R.id.dialog_message_send_et).view();
                    etMsg.setText(etMsg.getEditableText().append(emoji.getBoxName()));
                    etMsg.setTag(emoji);
                    etMsg.setSelection(etMsg.getText().length());
                });
                FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
                transaction.add(R.id.dialog_message_send_emoji, emojiFragment);
                transaction.commitAllowingStateLoss();
            }, 100);

        } else if (chatUsersDialogFragment != null) {
            InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(INPUT_METHOD_SERVICE);
            if (imm.isActive()) {//isOpen若返回true，则表示输入法打开
                imm.hideSoftInputFromWindow($.id(R.id.dialog_message_send_et).view().getWindowToken(), 0);
            }

            $.id(R.id.dialog_private_chat_users).gone();
            FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
            transaction.remove(chatUsersDialogFragment);
            if (Build.VERSION.SDK_INT >= 24) {
                transaction.commitNowAllowingStateLoss();
            } else {
                transaction.commitAllowingStateLoss();
            }
            chatUsersDialogFragment = null;

            $.id(R.id.dialog_message_send_emoji).visible();
            emojiFragment = EmojiFragment.newInstance();
            EmojiPresenter emojiPresenter = new EmojiPresenter(emojiFragment);
            emojiPresenter.setRouter(presenter.getLiveRouterListener());
            emojiFragment.setPresenter(emojiPresenter);
            emojiFragment.setCallBack(emoji -> {
                EditText etMsg = (EditText) $.id(R.id.dialog_message_send_et).view();
                etMsg.setText(etMsg.getEditableText().append(emoji.getBoxName()));
                etMsg.setSelection(etMsg.getText().length());
                etMsg.setTag(emoji);
            });
            FragmentTransaction _transaction = getChildFragmentManager().beginTransaction();
            _transaction.add(R.id.dialog_message_send_emoji, emojiFragment);
            _transaction.commitAllowingStateLoss();

        } else {

            $.id(R.id.dialog_message_send_emoji).gone();
            FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
            transaction.remove(emojiFragment);
            if (Build.VERSION.SDK_INT >= 24) {
                transaction.commitNowAllowingStateLoss();
            } else {
                transaction.commitAllowingStateLoss();
            }
            emojiFragment = null;

            InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.showSoftInput($.id(R.id.dialog_message_send_et).view(), InputMethodManager.SHOW_IMPLICIT);
        }
    }

    @Override
    public void onPictureSend() {
        dismissAllowingStateLoss();
    }


    @Override
    public void setChatQuickReplyList(List<String> chatQuickReplyList) {
        // 添加新加进来的快捷回复词
        for (String quickReply : chatQuickReplyList) {
            if (!mChatQuickReplyMap.containsKey(quickReply)) {
                mChatQuickReplyMap.put(quickReply, 0);
            }
        }
        // 删除远端已删除的快捷回复词
        List<String> deleteQuickReplyList = new ArrayList<>();
        for (String quickReply : mChatQuickReplyMap.keySet()) {
            if (!chatQuickReplyList.contains(quickReply)) {
                deleteQuickReplyList.add(quickReply);
            }
        }
        for (String quickReply : deleteQuickReplyList) {
            mChatQuickReplyMap.remove(quickReply);
        }
        if (mChatQuickReplyMap.isEmpty()) {
            $.id(R.id.dialog_quick_reply_sclv).gone();
            $.id(R.id.dialog_divider_line).gone();
        } else {
            $.id(R.id.dialog_quick_reply_sclv).visible();
            $.id(R.id.dialog_divider_line).visible();
            updateChatQuickReplyArea();
        }
    }


    private void updateChatQuickReplyArea() {
        if (mChatQuickReplyMap.isEmpty()) {
            return;
        }
        // 先排序
        List<Map.Entry<String, Integer>> chatQuickReplyList = new ArrayList<>(mChatQuickReplyMap.entrySet());
        Collections.sort(chatQuickReplyList, (o1, o2) -> o2.getValue().compareTo(o1.getValue()));

        ((LinearLayout) $.id(R.id.dialog_quick_reply_container).view()).removeAllViews();
        for (Map.Entry<String, Integer> chatQuickReply : chatQuickReplyList) {
            TextView textView = new TextView(getContext());
            textView.setTextColor(Color.parseColor("#FF999999"));
            textView.setText(chatQuickReply.getKey());
            textView.setBackground(ContextCompat.getDrawable(getContext(), R.drawable.bjy_bg_chat_quick_reply));
            LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            layoutParams.setMargins(20, 0, 20, 0);
            textView.setPadding(11, 4, 11, 4);
            textView.setOnClickListener(v -> {
                EditText editText = ((EditText) $.id(R.id.dialog_message_send_et).view());
                editText.post(() -> {
                    editText.setText(textView.getText());
                    editText.setSelection(textView.getText().length());
                });
                int count = mChatQuickReplyMap.get(textView.getText()) + 1;
                mChatQuickReplyMap.put((String) textView.getText(), count);
            });
            ((LinearLayout) $.id(R.id.dialog_quick_reply_container).view()).addView(textView, layoutParams);
        }
    }

    private class MessageTextWatcher implements android.text.TextWatcher {

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            // do nothing
        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            if (TextUtils.isEmpty(s)) {
                $.id(R.id.dialog_message_send_btn).enable(false);
            } else {
                $.id(R.id.dialog_message_send_btn).enable(true);
            }
        }

        @Override
        public void afterTextChanged(Editable s) {
            // do nothing
        }
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        if (chatUsersDialogFragment != null) {
            chatUsersDialogFragment = null;
        }
    }

    class LengthFilter implements InputFilter {
        private final int mMax;

        public LengthFilter(int max) {
            mMax = max;
        }

        public CharSequence filter(CharSequence source, int start, int end, Spanned dest,
                                   int dstart, int dend) {
            int keep = mMax - (dest.length() - (dend - dstart));
            if (keep <= 0) {
                if(getContext() != null) {
                    Toast.makeText(getContext(), getContext().getString(R.string.bjy_live_chat_input_text_beyond_tips, mMax), Toast.LENGTH_SHORT).show();
                }
                return "";
            } else if (keep >= end - start) {
                return null; // keep original
            } else {
                keep += start;
                if (Character.isHighSurrogate(source.charAt(keep - 1))) {
                    --keep;
                    if (keep == start) {
                        return "";
                    }
                }
                return source.subSequence(start, keep);
            }
        }

        /**
         * @return the maximum length enforced by this input filter
         */
        public int getMax() {
            return mMax;
        }
    }
}
